home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / ms_sh21s.zip / SH210 / SRC / SH12.C < prev    next >
C/C++ Source or Header  |  1992-12-14  |  5KB  |  215 lines

  1. /* MS-DOS SHELL - TSEARCH functions
  2.  *
  3.  * MS-DOS SHELL - Copyright (c) 1990,1,2 Data Logic Limited and Charles Forsyth
  4.  *
  5.  * This code is based on (in part) the shell program written by Charles
  6.  * Forsyth and is subject to the following copyright restrictions.  The
  7.  * code for the extended (non BASIC) tsearch.3 functions is based on code
  8.  * written by Peter Valkenburg & Michiel Huisjes.  The following copyright
  9.  * conditions apply:
  10.  *
  11.  * 1.  Redistribution and use in source and binary forms are permitted
  12.  *     provided that the above copyright notice is duplicated in the
  13.  *     source form and the copyright notice in file sh6.c is displayed
  14.  *     on entry to the program.
  15.  *
  16.  * 2.  The sources (or parts thereof) or objects generated from the sources
  17.  *     (or parts of sources) cannot be sold under any circumstances.
  18.  *
  19.  *    $Header: /usr/users/istewart/src/shell/sh2.1/RCS/sh12_basic.c,v 1.1 1992/12/14 10:54:56 istewart Exp $
  20.  *
  21.  *    $Log: sh12_basic.c,v $
  22.  * Revision 1.1  1992/12/14  10:54:56  istewart
  23.  * BETA 215 Fixes and 2.1 Release
  24.  *
  25.  */
  26.  
  27. #include <sys/types.h>
  28. #include <stdio.h>
  29. #include <string.h>
  30. #include <setjmp.h>
  31. #include <unistd.h>
  32. #ifdef OS2
  33. #define INCL_DOSSESMGR
  34. #include <os2.h>            /* DOS functions declarations       */
  35. #else
  36. #include <dos.h>            /* DOS functions declarations       */
  37. #endif
  38. #include "sh.h"
  39.  
  40. /*
  41.  * Type for doubly linked AVL tree.
  42.  */
  43.  
  44. /*
  45.  * Definition for t.... functions
  46.  */
  47.  
  48. typedef struct _t_node {
  49.     char        *key;
  50.     struct _t_node    *llink;
  51.     struct _t_node    *rlink;
  52. } _t_NODE;
  53.  
  54. static void        _twalk (_t_NODE *,
  55.                 void (*)(const void *, VISIT, int), int);
  56. /*
  57.  * Basic Tree Processing Functions
  58.  */
  59.  
  60. /*
  61.  * Delete node with key
  62.  */
  63.  
  64. void    *tdelete (key, rootcp, compar)
  65. void    *key;
  66. void    **rootcp;
  67. int    (*compar)(const void *, const void *);
  68. {
  69.     _t_NODE        *p;        /* Parent of node to be deleted */
  70.     register _t_NODE    *q;        /* Successor node        */
  71.     register _t_NODE    *r;        /* Right son node        */
  72.     int            ans;        /* Result of comparison        */
  73.     register _t_NODE    **rootp = (_t_NODE **)rootcp;
  74.  
  75.     if ((rootp == (_t_NODE **)NULL) || ((p = *rootp) == (_t_NODE *)NULL))
  76.     return (void *)NULL;
  77.  
  78.     while ((ans = (*compar)(key, (*rootp)->key)) != 0)
  79.     {
  80.     p = *rootp;
  81.     rootp = (ans < 0) ? &(*rootp)->llink : &(*rootp)->rlink;
  82.  
  83.     if (*rootp == (_t_NODE *)NULL)
  84.         return (void *)NULL;
  85.     }
  86.  
  87.     r = (*rootp)->rlink;
  88.  
  89.     if ((q = (*rootp)->llink) == (_t_NODE *)NULL)
  90.         q = r;
  91.  
  92.     else if (r != (_t_NODE *)NULL)
  93.     {
  94.     if (r->llink == (_t_NODE *)NULL)
  95.     {
  96.         r->llink = q;
  97.         q = r;
  98.     }
  99.  
  100.     else
  101.     {
  102.         for (q = r->llink; q->llink != (_t_NODE *)NULL; q = r->llink)
  103.         r = q;
  104.  
  105.         r->llink = q->rlink;
  106.         q->llink = (*rootp)->llink;
  107.         q->rlink = (*rootp)->rlink;
  108.     }
  109.     }
  110.  
  111.     ReleaseMemoryCell ((char *) *rootp);
  112.     *rootp = q;
  113.     return (void *)p;
  114. }
  115.  
  116. /*
  117.  * Find node with key
  118.  */
  119.  
  120. void    *tfind (key, rootcp, compar)
  121. void    *key;            /* Key to be located            */
  122. void    **rootcp;        /* Address of the root of the tree    */
  123. int    (*compar)(const void *, const void *);
  124. {
  125.     register _t_NODE    **rootp = (_t_NODE **)rootcp;
  126.  
  127.     if (rootp == (_t_NODE **)NULL)
  128.     return (void *)NULL;
  129.  
  130.     while (*rootp != (_t_NODE *)NULL)
  131.     {
  132.     int    r = (*compar)(key, (*rootp)->key);
  133.  
  134.     if (r == 0)
  135.         return (void *)*rootp;
  136.  
  137.     rootp = (r < 0) ? &(*rootp)->llink : &(*rootp)->rlink;
  138.     }
  139.  
  140.     return (void *)NULL;
  141. }
  142.  
  143. /*
  144.  * Search for a node with key key and add it if appropriate
  145.  */
  146.  
  147. void    *tsearch (key, rootcp, compar)
  148. void    *key;            /* Key to be located            */
  149. void    **rootcp;        /* Address of the root of the tree    */
  150. int    (*compar)(const void *, const void *);
  151. {
  152.     register _t_NODE    **rootp = (_t_NODE **)rootcp;
  153.     register _t_NODE    *q;    /* New node if key not found */
  154.  
  155.     if (rootp == (_t_NODE **)NULL)
  156.     return (void *)NULL;
  157.  
  158.     while (*rootp != (_t_NODE *)NULL)
  159.     {
  160.     int    r = (*compar)(key, (*rootp)->key);
  161.  
  162.     if (r == 0)
  163.         return (void *)*rootp;
  164.  
  165.     rootp = (r < 0) ? &(*rootp)->llink : &(*rootp)->rlink;
  166.     }
  167.  
  168.     q = (_t_NODE *) GetAllocatedSpace (sizeof (_t_NODE));
  169.  
  170.     if (q != (_t_NODE *)NULL)
  171.     {
  172.         SetMemoryAreaNumber ((void *)q, 0);
  173.     *rootp = q;
  174.     q->key = key;
  175.     q->llink = q->rlink = (_t_NODE *)NULL;
  176.     }
  177.  
  178.     return (void *)q;
  179. }
  180.  
  181.  
  182. /* Walk the nodes of a tree */
  183.  
  184. void    twalk (root, action)
  185. void    *root;            /* Root of the tree to be walked */
  186. void    (*action)(const void *, VISIT, int);
  187. {
  188.     if ((root != (char *)NULL) && (action != NULL))
  189.     _twalk (root, action, 0);
  190. }
  191.  
  192. static void        _twalk (root, action, level)
  193. register _t_NODE    *root;
  194. register void        (*action)(const void *, VISIT, int);
  195. register int        level;
  196. {
  197.     if (root->llink == (_t_NODE *)NULL && root->rlink == NULL)
  198.     (*action)(root, leaf, level);
  199.  
  200.     else
  201.     {
  202.     (*action)(root, preorder, level);
  203.  
  204.     if (root->llink != (_t_NODE *)NULL)
  205.         _twalk (root->llink, action, level + 1);
  206.  
  207.     (*action)(root, postorder, level);
  208.  
  209.     if (root->rlink != (_t_NODE *)NULL)
  210.         _twalk (root->rlink, action, level + 1);
  211.  
  212.     (*action)(root, endorder, level);
  213.     }
  214. }
  215.